
#include "Presentation.h"


Presentation::Presentation(const std::string &title_, const std::string &author_) : 
        title(title_), author(author_) {
    //pull data immediate to Presentation, but do not populate list of Songs

    SQLRETURN rv;
	SQLHSTMT hstmt = SQL_NULL_HANDLE;

    RaiiSQLAllocHandle alloc(SQL_HANDLE_STMT, hdbc, &hstmt);
	rv = alloc.result();
	if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to allocate a statement handle");
	}

	//title and author should have already been sterilized if necessary

	stringstream squery;
	squery <<	"SELECT presentation_comment "
				"FROM presentation "
				"WHERE presentation_tile = " << title << " "
				"AND author = " << author;
	string query;
	getline(squery, query);

	rv = SQLExecDirect(hstmt, (SQLCHAR*)query.c_str(), SQL_NTS);

    if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to execute SQL statement");
	}
	
	SQLCHAR pres_comment[1001];
	SQLINTEGER pres_comment_len;

	rv = SQLBindCol(hstmt, 1, SQL_C_CHAR, pres_comment, sizeof(pres_comment), &pres_comment_len);

	if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to bind column 1 (presentation_comment)");
	}

	//we can pull the dates once the Date class is implemented

	if((rv = SQLFetch(hstmt)) == SQL_NO_DATA || ODBC_FAILED(rv)) {
        display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to fetch immediate presentation data");
	}

	comment.assign(pres_comment, pres_comment_len);
}

Presentation::~Presentation() {
    clear();
}

void Presentation::load() {
    //populate list of Songs, but do not load them

    
}

void Presentation::clear() {
    for(int i=0; i < data.size(); ++i) {
        data.at(i)->clear();
    }

    Base::clear();
}


PresentationList::PresentationList(const SongList *song_list_) : 
        song_list(song_list_) {
    
}

PresentationList::~PresentationList() {
    clear();
}

void PresentationList::load() {
    //populate list of Presentations

    SQLRETURN rv;
	SQLHSTMT hstmt = SQL_NULL_HANDLE;

    RaiiSQLAllocHandle alloc(SQL_HANDLE_STMT, hdbc, &hstmt);
	rv = alloc.result();
	if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to allocate a statement handle");
	}

	rv = SQLExecDirect(hstmt, (SQLCHAR*)
	            "SELECT author, presentation_title "
				"FROM presentation "
				"ORDER BY author, presentation_title", 
	        SQL_NTS);

    if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to execute SQL statement");
	}
	
	SQLCHAR pres_author[41];
	SQLINTEGER pres_author_len;

	rv = SQLBindCol(hstmt, 1, SQL_C_CHAR, pres_author, sizeof(pres_author), &pres_author_len);

	if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to bind column 1 (author)");
	}
	
	SQLCHAR pres_title[21];
	SQLINTEGER pres_title_len;

	rv = SQLBindCol(hstmt, 2, SQL_C_CHAR, pres_title, sizeof(pres_title), &pres_title_len);

	if(ODBC_FAILED(rv)) {
		display_diagnostics(SQL_HANDLE_STMT, hstmt);
		throw SqlException("Failed to bind column 2 (presentation_title)");
	}

	
	while((rv = SQLFetch(hstmt)) != SQL_NO_DATA) {
		if(ODBC_FAILED(rv)) {
            display_diagnostics(SQL_HANDLE_STMT, hstmt);
		    throw SqlException("Failed to fetch data");
		}

		data.push_back(new Presentation(hdbc, song_list, pres_title, pres_author));
	}
}

void PresentationList::clear() {
    for(int i=0; i < data.size(); ++i) {
        data.at(i)->clear();
    }

    Base::clear();
}

